﻿
using KstopaSmartPlc.Services.Smart;
using System.Configuration;
using System.IO;

namespace OP10
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : PrismApplication
    {

        protected override async void OnInitialized()
        {

#if DEBUG
            var Url = ConfigurationManager.AppSettings["DebugUrl"];

#else   
            var Url = ConfigurationManager.AppSettings["ReleaseUrl"];
#endif

            //var smartService = ContainerLocator.Container.Resolve<ISmartService>();
            //try
            //{
            //    await smartService.SetHostUrl(Url);
            //    if (await smartService.ConnectAsync())
            //    {
            //        await smartService.JoinGroup("OP10");
            //    }

            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show("连接失败！请联系管理员");

            //    Environment.Exit(0);
            //}

            base.OnInitialized();
        }

        private static Mutex mutex;
        protected override Window CreateShell()
        {
            MainWindow sell = null;
            mutex = new Mutex(true, "OP10");
            if (mutex.WaitOne(0, false))
            {
                /**
               * 当前用户是管理员的时候，直接启动应用程序
               * 如果不是管理员，则使用启动对象启动程序，以确保使用管理员身份运行
               */
                //获得当前登录的Windows用户标示
                System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
                System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
                //判断当前登录用户是否为管理员
                //if (principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
                if (true)
                {
                    //如果是管理员，则直接运行
                    sell = Container.Resolve<MainWindow>();
                }
                else
                {
                    MessageBox.Show("请以管理员身份运行该程序！", "提示");
                    //退出
                    this.Shutdown();
                }
            }
            else
            {
                MessageBox.Show("已经有一个软件运行中，请勿重复开启！", "提示");
                this.Shutdown();
            }
            return sell;
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {

            containerRegistry.RegisterSingleton<ISmartService, SmartService>();

            containerRegistry.AddAutoMapper();

            containerRegistry.AddViews();
        }


        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
            RegisterEvents();//注册全局异常捕获
        }


        protected override IContainerExtension CreateContainerExtension()
        {
            var serviceCollection = new ServiceCollection();

            //NLog
            FileTarget fileTarget = new FileTarget();
            fileTarget.Name = "Kstopa";
            fileTarget.FileName = "${basedir}/logs/${shortdate}.log";
            fileTarget.Layout = Layout.FromString("${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}");
            var config = new LoggingConfiguration();
            config.AddTarget(fileTarget);
            config.AddRuleForAllLevels("Kstopa");
            var option = new NLogProviderOptions();

            serviceCollection.AddLogging(configure =>
            {
                configure.ClearProviders();
                configure.SetMinimumLevel(LogLevel.Trace);
                configure.AddNLog(config);
            });

            return new DryIocContainerExtension(new Container(CreateContainerRules())
            .WithDependencyInjectionAdapter(serviceCollection)
            );
        }



        /// <summary>
        /// 注册事件
        /// </summary>
        private void RegisterEvents()
        {
            //Task线程内未捕获异常处理事件
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

            //UI线程未捕获异常处理事件（UI主线程）
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;

            //非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        }
        /// <summary>
        /// Task线程内未捕获异常处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
        {
            try
            {
                var exception = e.Exception as Exception;
                if (exception != null)
                {
                    HandleException(exception);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                e.SetObserved();//设置该异常已察觉（这样处理后就不会引起程序崩溃）
            }
        }

        //非UI线程未捕获异常处理事件(例如自己创建的一个子线程)      
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                var exception = e.ExceptionObject as Exception;
                if (exception != null)
                {
                    HandleException(exception);
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                //ignore
            }
        }

        //UI线程未捕获异常处理事件（UI主线程）
        private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            try
            {
                HandleException(e.Exception);
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
            finally
            {
                //处理完后，我们需要将Handler=true表示已此异常已处理过
                e.Handled = true;
            }
        }
        private void HandleException(Exception e)
        {
            //将异常信息写入到日志文件
            FileLog.Log(e.ToString());
        }
    }

}
